package ch.subgate.chessvisualizationtrainer.widgets;

import java.util.ArrayList;
import ch.subgate.chessvisualizationtrainer.utils.ChessPiece;
import ch.subgate.chessvisualizationtrainer.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

public class ChessBoardView  extends View {
	
	private Bitmap mBoard;
	private Bitmap mHighlight;
	private Bitmap mWhitePawn;
	private Bitmap mWhiteRook;
	private Bitmap mWhiteKnight;
	private Bitmap mWhiteBishop;
	private Bitmap mWhiteQueen;
	private Bitmap mWhiteKing;
	private Bitmap mBlackPawn;
	private Bitmap mBlackRook;
	private Bitmap mBlackKnight;
	private Bitmap mBlackBishop;
	private Bitmap mBlackQueen;
	private Bitmap mBlackKing;
	
	private ArrayList<ChessPiece> mPieces;
	
	private int mSX1, mSY1, mSX2, mSY2, mSX3, mSY3;
	
	private float mSquareHeight;
	private float mSquareWidth;

	public ChessBoardView(Context context, AttributeSet attrs) {
		super(context, attrs);
		
		mBoard = BitmapFactory.decodeResource(getResources(), R.drawable.cb);
		
		mHighlight = BitmapFactory.decodeResource(getResources(), R.drawable.sq_highlight);
		mWhitePawn = BitmapFactory.decodeResource(getResources(), R.drawable.w_p);
		mWhiteRook = BitmapFactory.decodeResource(getResources(), R.drawable.w_r);
		mWhiteKnight = BitmapFactory.decodeResource(getResources(), R.drawable.w_n);
		mWhiteBishop = BitmapFactory.decodeResource(getResources(), R.drawable.w_b);
		mWhiteQueen = BitmapFactory.decodeResource(getResources(), R.drawable.w_q);
		mWhiteKing = BitmapFactory.decodeResource(getResources(), R.drawable.w_k);
		mBlackPawn = BitmapFactory.decodeResource(getResources(), R.drawable.b_p);
		mBlackRook = BitmapFactory.decodeResource(getResources(), R.drawable.b_r);
		mBlackKnight = BitmapFactory.decodeResource(getResources(), R.drawable.b_n);
		mBlackBishop = BitmapFactory.decodeResource(getResources(), R.drawable.b_b);
		mBlackQueen = BitmapFactory.decodeResource(getResources(), R.drawable.b_q);
		mBlackKing = BitmapFactory.decodeResource(getResources(), R.drawable.b_k);
		
		mPieces = null;
		
		unsetSquares();
		
		mSquareWidth = 0.0f;
		mSquareHeight = 0.0f;
	}
	
	@Override
	public void onDraw(Canvas canvas) {
		mSquareWidth = (float)this.getMeasuredWidth() / 8.0f;
		mSquareHeight = (float)this.getMeasuredHeight() / 8.0f;
		
		//Fill the canvas with white
		canvas.drawColor(0xffffffff);
		
		//Draw board, highlighted squares and pieces
		drawBoard(canvas);
		drawHighlight(canvas);
		drawPieces(canvas);
	}
	
	public void drawBoard(Canvas canvas) {
		if (mBoard != null) {
			//The bitmap is scaled to fit the view size
			RectF r = new RectF(0.0f, 0.0f, (float)this.getMeasuredWidth(), (float)this.getMeasuredHeight());
			canvas.drawBitmap(mBoard, null, r, null);
		}
		else {
			// Fallback if unable to load the board bitmaps
			// TODO
		}
	}
	
	public void drawHighlight(Canvas canvas) {
		if (mHighlight != null) {
			RectF r = new RectF();
			if (mSX1 != 0 && mSY1 != 0) {
				r.set(
						((float)mSX1 - 1.0f) * mSquareWidth,
						(8.0f - (float)mSY1) * mSquareHeight,
						(float)mSX1 * mSquareWidth,
						(8.0f - ((float)mSY1 - 1.0f)) * mSquareHeight);
				canvas.drawBitmap(mHighlight, null, r, null);
			}
			
			if (mSX2 != 0 && mSY2 != 0) {
				r.set(
						((float)mSX2 - 1.0f) * mSquareWidth,
						(8.0f - (float)mSY2) * mSquareHeight,
						(float)mSX2 * mSquareWidth,
						(8.0f - ((float)mSY2 - 1.0f)) * mSquareHeight);
				canvas.drawBitmap(mHighlight, null, r, null);
			}
			
			if (mSX3 != 0 && mSY3 != 0) {
				r.set(
						((float)mSX3 - 1.0f) * mSquareWidth,
						(8.0f - (float)mSY3) * mSquareHeight,
						(float)mSX3 * mSquareWidth,
						(8.0f - ((float)mSY3 - 1.0f)) * mSquareHeight);
				canvas.drawBitmap(mHighlight, null, r, null);
			}
		}
	}
	
	public void drawPieces(Canvas canvas) {
		if (mPieces != null) {
			RectF r = new RectF();
			for (ChessPiece piece : mPieces) {
				r.set(
					((float)(piece.getX()) - 1.0f) * mSquareWidth,
					(8.0f - (float)(piece.getY())) * mSquareHeight,
					(float)(piece.getX()) * mSquareWidth,
					(8.0f - ((float)(piece.getY()) - 1.0f)) * mSquareHeight);
				if (piece.getColor().equalsIgnoreCase("w")) {
					if (piece.getType().equalsIgnoreCase("p"))
						canvas.drawBitmap(mWhitePawn, null, r, null);
					else if (piece.getType().equalsIgnoreCase("r"))
						canvas.drawBitmap(mWhiteRook, null, r, null);
					else if (piece.getType().equalsIgnoreCase("n"))
						canvas.drawBitmap(mWhiteKnight, null, r, null);
					else if (piece.getType().equalsIgnoreCase("b"))
						canvas.drawBitmap(mWhiteBishop, null, r, null);
					else if (piece.getType().equalsIgnoreCase("q"))
						canvas.drawBitmap(mWhiteQueen, null, r, null);
					else if (piece.getType().equalsIgnoreCase("k"))
						canvas.drawBitmap(mWhiteKing, null, r, null);
				}
				else {
					if (piece.getType().equalsIgnoreCase("p"))
						canvas.drawBitmap(mBlackPawn, null, r, null);
					else if (piece.getType().equalsIgnoreCase("r"))
						canvas.drawBitmap(mBlackRook, null, r, null);
					else if (piece.getType().equalsIgnoreCase("n"))
						canvas.drawBitmap(mBlackKnight, null, r, null);
					else if (piece.getType().equalsIgnoreCase("b"))
						canvas.drawBitmap(mBlackBishop, null, r, null);
					else if (piece.getType().equalsIgnoreCase("q"))
						canvas.drawBitmap(mBlackQueen, null, r, null);
					else if (piece.getType().equalsIgnoreCase("k"))
						canvas.drawBitmap(mBlackKing, null, r, null);
				}
			}
		}
	}
	
	public void unsetPieces() {
		mPieces = null;
	}
	
	public void setPieces(ArrayList<ChessPiece> pieces) {
		mPieces = pieces;
		invalidate();
	}
	
	public void unsetSquares() {
		mSX1 = mSY1 = mSX2 = mSY2 = mSX3 = mSY3 = 0;
		// Request the surface to redraw
		invalidate();
	}
	
	public void setSquares(int x1, int y1) {
		mSX1 = x1;
		mSY1 = y1;
		mSX2 = mSY2 = mSX3 = mSY3 = 0;
		// Request the surface to redraw
		invalidate();
	}
	
	public void setSquares(int x1, int y1, int x2, int y2) {
		mSX1 = x1;
		mSY1 = y1;
		mSX2 = x2;
		mSY2 = y2;
		mSX3 = mSY3 = 0;
		// Request the surface to redraw
		invalidate();
	}
	
	public void setSquares(int x1, int y1, int x2, int y2, int x3, int y3) {
		mSX1 = x1;
		mSY1 = y1;
		mSX2 = x2;
		mSY2 = y2;
		mSX3 = x3;
		mSY3 = y3;
		// Request the surface to redraw
		invalidate();
	}
	
	public void dismiss() {
		mBoard.recycle();
		mHighlight.recycle();
		mWhitePawn.recycle();
		mWhiteRook.recycle();
		mWhiteKnight.recycle();
		mWhiteBishop.recycle();
		mWhiteQueen.recycle();
		mWhiteKing.recycle();
		mBlackPawn.recycle();
		mBlackRook.recycle();
		mBlackKnight.recycle();
		mBlackBishop.recycle();
		mBlackQueen.recycle();
		mBlackKing.recycle();
	}
	
}
